<template>
    <el-dialog v-model="showWordPreview" title="" fullscreen :show-close="false" destroy-on-close @open="renderHtml">
        <!-- 自定义标题 -->
        <template #header="{ close, titleId, titleClass }">
            <div class="my-header">
                <h4 :id="titleId" :class="titleClass">Word 预览</h4>
                <el-button type="danger" @click="close">
                    <el-icon class="el-icon--left"><CircleCloseFilled /></el-icon>
                    关闭
                </el-button>
            </div>
        </template>
        <!-- 预览文档 -->
        <div ref="wordContainer" id="word-preview"></div>
    </el-dialog>
</template>

<script setup lang="ts">
import { CircleCloseFilled } from '@element-plus/icons-vue';
import * as mammoth from 'mammoth';

// 自定义model
const showWordPreview = defineModel('showWordPreview', { default: false, type: Boolean, required: true });
// Excel 数据
const props = defineProps<{
    wordData: ArrayBuffer | undefined;
}>();
// 表格ref
const wordContainer = ref<HTMLElement | undefined>();

// 监听showExcelPreview变化
watch(
    () => showWordPreview.value,
    async () => {
        if (showWordPreview.value) {
            await renderHtml();
        }
    }
);

// 样式映射，添加 mammoth- 前缀提高特异性
const styleMap = [
    /* *************************段落样式************************* */
    // 标题样式
    "p[style-name='Title'] => h1.mammoth-title:fresh",
    "p[style-name='Heading 1'] => h1.mammoth-h1:fresh",
    "p[style-name='Heading 2'] => h2.mammoth-h2:fresh",
    "p[style-name='Heading 3'] => h3.mammoth-h3:fresh",
    "p[style-name='Heading 4'] => h4.mammoth-h4:fresh",
    "p[style-name='Heading 5'] => h5.mammoth-h5:fresh",
    "p[style-name='Heading 6'] => h6.mammoth-h6:fresh",

    // 正文样式，保留空格
    "p[style-name='Normal'] => p.mammoth-normal:fresh[data-white-space='pre-wrap']",
    "p[style-name='Body Text'] => p.mammoth-body-text:fresh[data-white-space='pre-wrap']",
    "p[style-name='Body Text 2'] => p.mammoth-body-text-2:fresh[data-white-space='pre-wrap']",
    "p[style-name='Body Text 3'] => p.mammoth-body-text-3:fresh[data-white-space='pre-wrap']",

    // 列表样式
    "p[style-name='List Paragraph'] => p.mammoth-list-paragraph:fresh",
    "p[style-name='List Bullet'] => p.mammoth-list-bullet:fresh",
    "p[style-name='List Number'] => p.mammoth-list-number:fresh",
    "p[style-name='List Continue'] => p.mammoth-list-continue:fresh",

    // 引用样式
    "p[style-name='Quote'] => blockquote.mammoth-quote > p.mammoth-quote-p:fresh",
    "p[style-name='Intense Quote'] => blockquote.mammoth-intense-quote > p.mammoth-intense-quote-p:fresh",

    // 其他特殊段落
    "p[style-name='Footer'] => p.mammoth-footer:fresh",
    "p[style-name='Header'] => p.mammoth-header:fresh",
    "p[style-name='Caption'] => p.mammoth-caption:fresh",
    "p[style-name='TOC Heading'] => p.mammoth-toc-heading:fresh",

    /* *************************字符样式************************* */
    // 强调文本
    "r[style-name='Emphasis'] => em.mammoth-emphasis:fresh",
    "r[style-name='Strong'] => strong.mammoth-strong:fresh",
    "r[style-name='Intense Emphasis'] => em.mammoth-intense-emphasis:fresh",
    "r[style-name='Subtle Emphasis'] => em.mammoth-subtle-emphasis:fresh",

    // 代码和键盘输入
    "r[style-name='Code'] => code.mammoth-code:fresh",
    "r[style-name='Keyboard'] => kbd.mammoth-keyboard:fresh",

    // 链接
    "r[style-name='Hyperlink'] => a.mammoth-hyperlink:fresh",

    // 其他字符样式
    "r[style-name='Book Title'] => cite.mammoth-book-title:fresh",
    "r[style-name='Subtle Reference'] => span.mammoth-subtle-ref:fresh",
    "r[style-name='Intense Reference'] => span.mammoth-intense-ref:fresh",

    /* *************************表格样式************************* */
    // 表格整体样式
    "table[style-name='Normal Table'] => table.mammoth-normal-table:fresh",
    "table[style-name='Light Shading'] => table.mammoth-light-shading:fresh",
    "table[style-name='Light List'] => table.mammoth-light-list:fresh",
    "table[style-name='Light Grid'] => table.mammoth-light-grid:fresh",

    // 表格单元格样式
    "table[style-name='Table Grid'] => table.mammoth-grid:fresh",
    "p[style-name='Table Heading'] => th.mammoth-table-heading > p.mammoth-table-heading-p:fresh",
    "p[style-name='Table Text'] => td.mammoth-table-text > p.mammoth-table-text-p:fresh",

    /* *************************列表样式************************* */
    // 无序列表
    "list[style-name='List Bullet'] => ul.mammoth-bullet:fresh",
    "list[style-name='List Bullet 2'] => ul.mammoth-bullet-2:fresh",
    "list[style-name='List Bullet 3'] => ul.mammoth-bullet-3:fresh",

    // 有序列表
    "list[style-name='List Number'] => ol.mammoth-number:fresh",
    "list[style-name='List Number 2'] => ol.mammoth-number-2:fresh",
    "list[style-name='List Number 3'] => ol.mammoth-number-3:fresh",

    // 多级列表
    "list[style-name='List Multilevel'] => ul.mammoth-multilevel:fresh",
    "list[style-name='List Continue'] => li.mammoth-continue:fresh",

    /* *************************自定义样式映射************************* */
    // 基于段落属性的映射
    "p[alignment='center'] => p.mammoth-center:fresh",
    "p[alignment='right'] => p.mammoth-right:fresh",
    "p[alignment='justify'] => p.mammoth-justify:fresh",

    // 基于缩进的映射
    "p[indent='1'] => p.mammoth-indent-1:fresh",
    "p[indent='2'] => p.mammoth-indent-2:fresh",

    // 基于行距的映射
    "p[line-spacing='1.5'] => p.mammoth-line-spacing-1-5:fresh",
    "p[line-spacing='2'] => p.mammoth-line-spacing-2:fresh",

    // 基于字体属性的映射
    "r[font-size='24pt'] => span.mammoth-font-size-24:fresh",
    "r[font-color='FF0000'] => span.mammoth-red-text:fresh",
    "r[font-family='Arial'] => span.mammoth-arial:fresh",
    "r[bold='true'] => strong.mammoth-bold:fresh",
    "r[italic='true'] => em.mammoth-italic:fresh",
    "r[underline='true'] => u.mammoth-underline:fresh",
    "r[strikethrough='true'] => del.mammoth-strikethrough:fresh",

    /* *************************高级组合映射************************* */
    // 组合多个属性的映射
    "p[style-name='Heading 1'][alignment='center'] => h1.mammoth-h1-center:fresh",
    "r[style-name='Emphasis'][italic='true'] => em.mammoth-emphasis-italic:fresh",

    // 保留原始样式
    'p => p.mammoth-default:fresh',
    'r => span.mammoth-default-span:fresh',
    'table => table.mammoth-default-table:fresh',
];

// 渲染html
const renderHtml = async () => {
    // 解析文件
    const result = await mammoth.convertToHtml(
        { arrayBuffer: props.wordData as ArrayBuffer },
        {
            styleMap,
        }
    );

    if (!wordContainer.value) {
        return;
    }
    wordContainer.value.innerHTML = result.value;
};
</script>

<style scoped lang="scss">
.my-header {
    display: flex;
    flex-direction: row;
    justify-content: space-between;
    gap: 16px;
}
</style>
